package com.sinitek.model.service;

import com.sinitek.enums.AggregationEnum;
import com.sinitek.model.query.MustNotQuery;
import com.sinitek.model.query.MustQuery;
import com.sinitek.model.query.ShouldQuery;
import com.sinitek.page.Page;
import com.sinitek.web.request.BasePageRequest;

import java.util.Map;

public interface BaseEsService<T> {

    /**
     * 通过编号删除文档
     *
     * @param indexName (索引名)
     * @param type      (类型名)
     * @param _id       (_id)
     * @return
     */
    Boolean deleteById(String indexName, String type, String _id);

    /**
     * 更新文档
     *
     * @param t         (对象)
     * @param indexName (索引名)
     * @param type      (类型名)
     * @param _id       (_id)
     * @return
     */
    T update(T t, String indexName, String type, String _id);

    /**
     * 保存文档
     *
     * @param t         (对象)
     * @param indexName (索引名)
     * @param type      (类型名)
     * @return
     */
    T save(T t, String indexName, String type);

    /**
     * 通过文档编号查询
     *
     * @param id
     * @return
     */
    T findById(String indexName, String type, String id);

    /**
     * 索引查询 (模糊匹配)
     *
     * @param indexName     (文档索引名)
     * @param sortFieldName (排序字段名)
     * @param sortOrder     (排序方式)
     * @param page          (分页对象)
     * @return
     */
    Page<Map<String, Object>> findAllMatch(String indexName,
                                           String sortFieldName,
                                           String sortOrder,
                                           BasePageRequest page);

    /**
     * 关键词查询 (模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param searchFieldName (检索的字段名称)
     * @param page            (分页对象)
     * @param keyWord         (搜索关键词)
     * @return
     */
    Page<Map<String, Object>> findAllMatchByKeyword(String indexName,
                                                    String sortFieldName,
                                                    String sortOrder,
                                                    String searchFieldName,
                                                    BasePageRequest page,
                                                    String keyWord
    );


    /**
     * 多关键词匹配某一字段查询
     * 通过索引名称、排序字段、关键词、分页参数获取文档集合(分词精确查询)
     * 只要满足一个就会返回。但是不会返回二者的并集。
     * ("key", obj) 完全匹配、("key", obj1, obj2..)一次匹配多个值
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param searchFieldName 检索的字段名称
     * @param page            (分页对象)
     * @param keyWords        (搜索多个关键词)
     * @return
     */
    Page<Map<String, Object>> findAllTermsByKeywords(String indexName,
                                                     String sortFieldName,
                                                     String sortOrder,
                                                     String searchFieldName,
                                                     BasePageRequest page,
                                                     String... keyWords);


    /**
     * 通过索引名称、排序字段、关键词、分页参数获取文档集合(分词精确查询)
     * 一种略高级的查询，充分考虑了stop-word的低优先级，提高了查询精确性。
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param searchFieldName (搜索的字段名称)
     * @param page            (分页对象)
     * @param keyWord         (搜索多个关键词)
     * @return
     */
    Page<Map<String, Object>> findAllCommonTermsByKeywords(String indexName,
                                                           String sortFieldName,
                                                           String sortOrder,
                                                           String searchFieldName,
                                                           BasePageRequest page,
                                                           Object keyWord);


    /**
     * 多字段匹配关键词查询 (模糊匹配)
     *
     * @param indexName        (文档索引名)
     * @param sortFieldName    (排序字段名)
     * @param sortOrder        (排序方式)
     * @param keyWord          (搜索关键词)
     * @param page             (分页对象)
     * @param searchFieldNames (搜索多个字段名称)
     * @return
     */
    Page<Map<String, Object>> findAllMultiMatchByKeywords(String indexName,
                                                          String sortFieldName,
                                                          String sortOrder,
                                                          String keyWord,
                                                          BasePageRequest page,
                                                          String... searchFieldNames);

    /**
     * 前缀关键词查询 chenlian* (模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param page            (分页对象)
     * @param searchFieldName (搜索的字段名称)
     * @param prefix          (关键词前缀)
     * @return
     */
    Page<Map<String, Object>> findAllByPrefix(String indexName,
                                              String sortFieldName,
                                              String sortOrder,
                                              BasePageRequest page,
                                              String searchFieldName,
                                              String prefix);


    /**
     * 重要 - 关键词模糊查询 (模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param page            (分页对象)
     * @param searchFieldName (搜索的字段名称)
     * @param keyword         (搜索关键词)
     * @return
     */
    Page<Map<String, Object>> findAllFuzzyByKeyWord(String indexName,
                                                    String sortFieldName,
                                                    String sortOrder,
                                                    BasePageRequest page,
                                                    String searchFieldName,
                                                    String keyword);


    /**
     * 重要 - 关键词通配符查询 * (模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param page            (分页对象)
     * @param searchFieldName (搜索的字段名称)
     * @param keyword         (搜索关键词)
     * @return
     */
    Page<Map<String, Object>> findAllWildcardByKeyWord(String indexName,
                                                       String sortFieldName,
                                                       String sortOrder,
                                                       BasePageRequest page,
                                                       String searchFieldName,
                                                       String keyword);

    /**
     * 重要 - 范围查询包含(模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param page            (分页对象)
     * @param searchFieldName (搜索的字段名称)
     * @param from            (搜索开始值 10001)
     * @param to              (搜索结束值 10004 结果包含 10001、10002、10003、10004)
     * @return
     */
    Page<Map<String, Object>> findAllRangeIncludeByCondition(String indexName,
                                                             String sortFieldName,
                                                             String sortOrder,
                                                             BasePageRequest page,
                                                             String searchFieldName,
                                                             Object from,
                                                             Object to);


    /**
     * 重要 - 范围查询不包含 (模糊匹配)
     *
     * @param indexName       (文档索引名)
     * @param sortFieldName   (排序字段名)
     * @param sortOrder       (排序方式)
     * @param page            (分页对象)
     * @param searchFieldName (搜索的字段名称)
     * @param from            (搜索开始值 10001)
     * @param to              (搜索结束值 10004 结果包含 10002、10003)
     * @return
     */
    Page<Map<String, Object>> findAllRangeUnIncludeByCondition(String indexName,
                                                               String sortFieldName,
                                                               String sortOrder,
                                                               BasePageRequest page,
                                                               String searchFieldName,
                                                               Object from,
                                                               Object to);

    /**
     * 重要 - 组合查询(精准匹配)
     *
     * @param indexName     (文档索引名)
     * @param sortFieldName (排序字段名)
     * @param sortOrder     (排序方式)
     * @param page          (分页对象)
     * @param mustQuery     (必须满足条件)
     * @param mustNotQuery  (必须不满足条件)
     * @param shouldQuery   (可能满足条件)
     * @return
     */
    Page<Map<String, Object>> findAllAssociationByCondition(String indexName,
                                                            String sortFieldName,
                                                            String sortOrder,
                                                            BasePageRequest page,
                                                            MustQuery mustQuery,
                                                            MustNotQuery mustNotQuery,
                                                            ShouldQuery shouldQuery);


    /**
     * 聚合查询 (MAX,MIN,COUNT,SUM,AVG)
     *
     * @param indexName       (文档索引名)
     * @param searchFieldName (搜索的字段名称)
     * @param templateName    (模板名称,自定义必须是英文)
     * @return
     */
    Map<String, Object> AggregationAll(String indexName,
                                       String searchFieldName,
                                       String templateName);

    /**
     * 聚合查询 通过条件
     *
     * @param indexName
     * @param searchFieldName
     * @param templateName
     * @param aggregationEnum (MAX,MIN,COUNT,SUM,AVG)
     * @return
     */
    Double AggregationAllByCondition(String indexName,
                                     String searchFieldName,
                                     String templateName,
                                     AggregationEnum aggregationEnum);


    //TODO 桶聚合、高亮

}
